home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / www / ludzie / txf / progs / anystrtolong.lha / AnyStrToLong / AnyStrToLong.asm < prev    next >
Assembly Source File  |  1996-11-21  |  5KB  |  258 lines

  1.  
  2. **********************************************************************
  3. *
  4. *    AnyStrToLong - convert ASCII string to 32-bit value
  5. *
  6. * Input:  a0 - null terminated string
  7. * Output: d0 - the value, or $FFFFFFFF if error
  8. *         d1 - success (boolean)
  9. *
  10. *    As string you can pass decimal (no prefix), binary (prefix '%')
  11. * or hex (prefixes '$' or '0x'). Check d1 for success or failure (fails
  12. * when non-specific characters are found, or if null string).
  13. *    In hex/bin mode, when you pass too many characters, only last
  14. * 8/32 are used. In dec mode, maximal value is 4.294.967.295
  15. * ($FFFFFFFF). Decimal values may be negative (prefix '-'), then the
  16. * range is from -2.147.483.647 to 2.147.483.648 (otherwise the result
  17. * is not reliable).
  18. *
  19. *    Alters only scratch registers (d0, d1, a0, a1). Uses 16 bytes
  20. * of stack (decimal mode only).
  21. *
  22. *
  23. *    © 1996 by Tadek Knapik (tadek@student.uci.agh.edu.pl).
  24. *         Public Domain. E-mail appreciated :-)
  25. *
  26. **********************************************************************
  27.  
  28.  
  29.  
  30. AnyStrToLong:
  31.     tst.b    (a0)            ;null string?
  32.     beq    AnyStrToLongError
  33.  
  34.     moveq    #0,d0            ;negative flag in decimal mode
  35.  
  36.     cmpi.b    #'-',(a0)        ;negative?
  37.     beq    DecStrToLong0
  38.  
  39.     cmpi.b    #'%',(a0)        ;binary?
  40.     beq    BinStrToLong0        ;yes!
  41.  
  42.     cmpi.b    #'$',(a0)        ;hex
  43.     beq    HexStrToLong0        ;yes!
  44.  
  45.     cmpi.b    #'0',(a0)        ;hex (0x)
  46.     bne    DecStrToLong        ;no!
  47.  
  48.     movea.l    a0,a1            ;string pointer
  49.     addq.l    #1,a1
  50.     cmpi.b    #'x',(a1)        ;'x'?
  51.     beq    HexStrPrefix        ;
  52.  
  53. HexStrPrefix:
  54.     cmpi.b    #'X',(a1)        ;'X'?
  55.     bne    DecStrToLong
  56.  
  57.     addq.l    #2,a0            ;omit '0x'
  58.     bra    HexStrToLong
  59.  
  60.  
  61. ;--------------------
  62.  
  63. ;convert hex to long.
  64.  
  65. HexStrToLong0:
  66.     addq.l    #1,a0            ;next byte (omit '$')
  67.  
  68. HexStrToLong:
  69.     moveq    #0,d0
  70.     moveq    #0,d1
  71.  
  72. HexNextNybble:
  73.     tst.b    (a0)            ;the end?
  74.     beq    AnyStrToLongEnd        ;yes
  75.  
  76. ;next character
  77.  
  78.     lsl.l    #4,d0            ;prepare next 4 bits
  79.     moveq    #0,d1            ;clr
  80.     move.b    (a0)+,d1        ;next cipher
  81.  
  82.     cmpi.b    #'0',d1            ;lower than 0?
  83.     blt    AnyStrToLongError
  84.  
  85.     cmpi.b    #'f',d1            ;higher than f?
  86.     bgt    AnyStrToLongError
  87.  
  88.     subi.b    #'0',d1            ;ASCII '0'
  89.     bmi    AnyStrToLongError
  90.  
  91. ;now we have 0-9. Or not..
  92.  
  93.     cmpi.b    #9,d1            ;more than '9'?
  94.     ble    HexReady        ;no, we're done
  95.  
  96.     subi.b    #7,d1            ;try this
  97.  
  98. ;If A-F, we have 10-15, unless <, >, @ etc., or a-f
  99.  
  100.     cmpi.b    #10,d1            ;less than 'A'?
  101.     blt    AnyStrToLongError    ;yes, jump @ Error
  102.  
  103.     cmpi.b    #15,d1            ;more than 'F'
  104.     ble    HexReady        ;OK
  105.  
  106. ;so, probably a-f
  107.  
  108.     subi.b    #32,d1            ;case change?
  109.  
  110.     cmpi.b    #10,d1            ;less?
  111.     blt    AnyStrToLongError    ;yes, probably XYZ
  112.  
  113.     cmpi.b    #15,d1            ;more than 'f'
  114.     ble    HexReady        ;no, OK
  115.     bra    AnyStrToLongError    ;error, probably xyz
  116.  
  117. ;in d1 we have value in range 0-15
  118.  
  119. HexReady:
  120.     or.b    d1,d0            ;set those bits
  121.     bra    HexNextNybble        ;next one, please
  122.  
  123.  
  124. AnyStrToLongError:
  125.     move.l    #-1,d0            ;if -1 in d0, then 
  126.     moveq    #0,d1            ;d1 is boolean failure
  127.     rts
  128.  
  129. AnyStrToLongEnd:
  130.     moveq    #1,d1            ;
  131.     rts
  132.  
  133. ;--------------------
  134.  
  135. ;convert binary to long.
  136.  
  137. BinStrToLong0:
  138.     addq.l    #1,a0            ;next byte
  139. BinStrToLong:
  140.     tst.b    (a0)            ;nothing?
  141.     beq    AnyStrToLongError
  142.  
  143.     moveq    #0,d0
  144.     moveq    #0,d1
  145.  
  146. BinNextBit:
  147.     tst.b    (a0)            ;coô jeszcze
  148.     beq    AnyStrToLongEnd
  149.  
  150. ;what do we have here..
  151.  
  152.     lsl.l    #1,d0            ;prepare next bit
  153.  
  154.     moveq    #0,d1
  155.     move.b    (a0)+,d1
  156.  
  157.     subi.b    #'0',d1            ;
  158.     bmi    AnyStrToLongError
  159.  
  160.     cmpi.b    #1,d1            ;more than 1?
  161.     bgt    AnyStrToLongError
  162.  
  163. ;now we have 0 or 1 in d1.
  164.  
  165.     or.b    d1,d0            ;to set or not to set
  166.     bra    BinNextBit
  167.  
  168. ;--------------------
  169.  
  170.  
  171. ;Convert decimal ASCII to 32 bit long.
  172. ;Maximum - 4.294.967.295 ($FFFFFFFF)
  173. ;If you pass in [x*4.294.967.295+y], it will probably return [y].
  174.  
  175.  
  176. DecStrToLong0:
  177.     addq.l    #1,a0            ;next byte (omit '-')
  178.     moveq    #1,d0
  179.  
  180. DecStrToLong:
  181.     tst.b    (a0)            ;nic?
  182.     beq    AnyStrToLongError
  183.     movem.l    d2-d5,-(sp)
  184.     move.l    d0,d5            ;negative flag
  185.  
  186.     moveq    #0,d1            ;clr
  187.     moveq    #0,d0            ;the value
  188.     movea.l    a0,a1            ;string
  189.     addq.l    #1,a1            ;cause I add immediately
  190.  
  191. ;length of the string without last null character
  192.  
  193. DecStrLengthLoop:
  194.     addq.l    #1,d1
  195.     tst.b    (a1)+
  196.     bne    DecStrLengthLoop    
  197.  
  198. ;now in d1 we have the weight  of the first cipher plus 1
  199.  
  200. DecNextCipherLoop:
  201.     subq.l    #1,d1            ;sub 1
  202.  
  203.     tst.l    d1            ;if null, this is the last one
  204.     beq    DecLastCipher
  205.     move.l    d1,d2
  206.  
  207.     moveq    #0,d3
  208.     move.b    (a0)+,d3        ;the cipher
  209.  
  210.     subi.b    #'0',d3            ;
  211.     bmi    DecStrToLongError    ;
  212.  
  213.     cmpi.b    #9,d3            ;
  214.     bgt    DecStrToLongError
  215.  
  216.  
  217. DecMultipleLoop:
  218.     move.l    d3,d4            ;copy it
  219.  
  220.     lsl.l    #3,d3            ;*8
  221.     lsl.l    #1,d4            ;*2
  222.     add.l    d4,d3            ;x*2+x*8=x*(2+8)=x*10
  223.  
  224.     subq.l    #1,d2
  225.     bne    DecMultipleLoop
  226.  
  227.     add.l    d3,d0            ;
  228.     bra    DecNextCipherLoop
  229.  
  230.  
  231. DecLastCipher:
  232.     moveq    #0,d3
  233.     move.b    (a0)+,d3
  234.  
  235.     subi.b    #'0',d3            ;
  236.     bmi    DecStrToLongError    ;
  237.  
  238.     cmpi.b    #9,d3            ;
  239.     bgt    DecStrToLongError
  240.  
  241.     add.l    d3,d0
  242.  
  243. DecStrToLongEnd:
  244.     tst.l    d5                ;was it negative?
  245.     beq    DecStrToLongPositiveEnd        ;
  246.     neg.l    d0                ;negate it
  247.  
  248. DecStrToLongPositiveEnd:
  249.     movem.l    (sp)+,d2-d5
  250.     bra    AnyStrToLongEnd
  251.  
  252. DecStrToLongError:
  253.     movem.l    (sp)+,d2-d5
  254.     bra    AnyStrToLongError
  255.  
  256. **********************************************************************
  257.  
  258.